#include <stdio.h>
#include <stm32f10x_gpio.h>
#include <stm32f10x_rcc.h>
#include <stm32f10x_tim.h>
#include <config.h>
#include <LED_driver.h>

static LED_style led_style_run;
static unsigned int delay = 0;
static unsigned int delay_tmp = 0;
static uint8_t flag_revert = 0;

/*
 *
 */
void LED_configuration(void) {
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10
			|GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14
			|GPIO_Pin_15;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
}

/*
 *
 */
void LED_active(LED_style ledStyle, unsigned int timedelay) {
	led_style_run = ledStyle;
	if ((timedelay >= 100) && (timedelay <= 2000)) {
		delay = timedelay;
	} else {
		OUTPUT_USARTTerm;
		puts("out of range, auto set LED's time delay to 500 ms\r\n");
		delay = 500;
	}
	delay_tmp = 0;
	GPIO_Write(GPIOB, GPIO_ReadOutputData(GPIOB) & 0x0F);
	Switch_timer_LED_IRQ(ENABLE);
}

/*************************************************************************
 * below is IRQhandler functions
 *
 *************************************************************************/
void TIM3_IRQHandler(void) {
	if (TIM_GetITStatus(TIM3, TIM_IT_Update) == SET) {
		uint16_t temp;
		if (delay_tmp < delay) {
			delay_tmp++;
		} else {
			delay_tmp = 0;
			temp = GPIO_ReadOutputData(GPIOB) >> 8;
			if (led_style_run == led_shr) {
				if (temp == 0x0) {
					temp = 0x80;
				} else {
					temp = temp >> 1;
				}
			} else if (led_style_run == led_shl) {
				if (temp == 0x0) {
					temp = 0x1;
				} else {
					temp = temp << 1;
				}
			} else if (led_style_run == led_inc_lr) {
				if (temp == 0xFF) {
					temp = 0x0;
				} else {
					temp = (temp >> 1) | 0x80;
				}
			} else if (led_style_run == led_inc_rl) {
				if (temp == 0xFF) {
					temp = 0x0;
				} else {
					temp = (temp << 1) | 0x1;
				}
			} else if (led_style_run == led_dec_lr) {
				if (temp == 0x0) {
					temp = 0xFF;
				} else {
					temp = (temp & 0x7F) >> 1;
				}
			} else if (led_style_run == led_dec_rl) {
				if (temp == 0x0) {
					temp = 0xFF;
				} else {
					temp = (temp & 0xFE) << 1;
				}
			} else if (led_style_run == led_incdec_lr) {
				if (flag_revert == 0) {
					if (temp == 0xFF) {
						flag_revert = 1;
					} else {
						temp = (temp >> 1) | 0x80;
					}
				} else {
					if (temp == 0x0) {
						flag_revert = 0;
					} else {
						temp = (temp & 0x7F) >> 1;
					}
				}
			} else if (led_style_run == led_incdec_rl) {
				if (flag_revert == 0) {
					if (temp == 0xFF) {
						flag_revert = 1;
					} else {
						temp = (temp << 1) | 0x1;
					}
				} else {
					if (temp == 0x0) {
						flag_revert = 0;
					} else {
						temp = (temp & 0xFE) << 1;
					}
				}
			}
			GPIO_Write(GPIOB, (GPIO_ReadOutputData(GPIOB) & (0x0F)) | temp << 8);
		}
		TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
	}
}
